package xyz.kail.demo.websocket.javax.boot.endpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * http://localhost:8080/ws.html
 * <p>
 * < ------
 * Request URL: ws://localhost:8080/ws/hello/123
 * <p>
 * Connection: Upgrade
 * Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
 * Sec-WebSocket-Key: wqb3CHA5LQZ6d3ISSEThxg==
 * Sec-WebSocket-Version: 13
 * Upgrade: websocket
 * ------ >
 * <p>
 * Connection: upgrade
 * Sec-WebSocket-Accept: EVMIN3qcxa4N2kl8ZxsCVPP0grk=
 * Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
 * Upgrade: websocket
 */
@Component
@ServerEndpoint(value = "/ws/hello/{userId}")
public class HelloEndPoint {

    private static Logger logger = LoggerFactory.getLogger(HelloEndPoint.class);

    /**
     * 连接时执行
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {

        logger.warn("用户 {} onOpen", userId);
        printSessionInfo(session);
        logger.info("");
    }


    /**
     * 收到消息时执行
     */
    @OnMessage
    public void onMessage(@PathParam("userId") String userId, String message, Session session) throws IOException {
        String text = "收到 " + userId + " 的消息 " + message;
        session.getBasicRemote().sendText(text);

        logger.warn(text);
        printSessionInfo(session);
        logger.info("");
    }

    /**
     * 连接错误时执行
     */
    @OnError
    public void onError(@PathParam("userId") String userId, Session session, Throwable ex) {
        logger.error("用户id为：{}的连接发送错误", userId, ex);

        printSessionInfo(session);
        logger.info("");
    }


    /**
     * 关闭时执行
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId, Session session, CloseReason closeReason) {
        logger.error("连接：{} 关闭", userId);
        logger.error("连接：{} 关闭", closeReason);

        printCloseReasonInfo(closeReason);
        printSessionInfo(session);
        logger.info("");
    }

    private static void printCloseReasonInfo(CloseReason closeReason) {
        logger.info("  关闭原因:{}", closeReason);
    }

    private static void printSessionInfo(Session session) {
        logger.info("  session.getId:{}", session.getId());
        logger.info("  session.getQueryString:{}", session.getQueryString());
        logger.info("  session.getPathParameters:{}", session.getPathParameters());
        logger.info("  session.getProtocolVersion:{}", session.getProtocolVersion());
        logger.info("  session.getNegotiatedSubprotocol:{}", session.getNegotiatedSubprotocol());
        logger.info("  session:{}", session);
    }
}
